package com.turingoal.common.util.media;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Locale;
import javax.imageio.ImageIO;
import lombok.Data;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import net.coobird.thumbnailator.name.Rename;

/**
 * 工具类-》媒体处理工具类-》图片处理工具类
 * <p>
 * [依赖 thumbnailator.jar]
 * </p>
 */
public final class ImageUtil {
	private ImageUtil() {
		throw new Error("工具类不能实例化！");
	}

	public static final float QUARTER = 0.25F; // 四分之一
	public static final float HALF = 0.5F; // 一半
	/**
	 * 图片的后缀
	 */
	public static final String[] IMAGE_EXT = new String[] { "jpg", "jpeg", "gif", "png", "bmp" };

	/**
	 * 批量处理
	 * 
	 * @param path
	 *            文件夹路径
	 * @param format
	 *            图片格式
	 * @param height
	 * @param width
	 */
	public static void doThumbs(final String path, final String format, final int height, final int width) {
		try {
			Thumbnails.of(new File(path).listFiles()).size(height, width).outputFormat(format).toFiles(Rename.PREFIX_DOT_THUMBNAIL);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成缩略图
	 */
	public static void doThumb(final File originFile, final File outFile, final int height, final int width) {
		try {
			Thumbnails.of(originFile).size(height, width).toFile(outFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成缩略图
	 */
	public static void doThumb(final String originPath, final String outPath, final int height, final int width) {
		try {
			Thumbnails.of(originPath).size(height, width).toFile(outPath);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成缩略图
	 * 
	 * @param rotate
	 *            旋转
	 */
	public static void doThumb(final File originFile, final File watermarkFile, final File outFile, final int rotate, final int height, final int width) {
		try {
			Thumbnails.of(originFile).size(height, width).rotate(rotate)
			// 旋转
					.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(watermarkFile), HALF).outputQuality(HALF).toFile(outFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 生成缩略图 加水印、旋转
	 * @param originFile // 源文件
	 * @param watermarkFile // 水印文件
	 * @param outFile // 输出文件
	 * @param rotate // 旋转
	 * @param markPosition // 水印位置（1：左上，2：右上，3：左下，4：右下，5：中央）
	 * @param height // 水印高度
	 * @param width // 水印宽度
	 */
	public static void doThumb(final File originFile, final File watermarkFile, final File outFile, final Integer rotate, final Integer markPosition) {
		Positions position = null;
		switch (markPosition) {
		case 1:
			position = Positions.TOP_LEFT;
			break;
		case 2:
			position = Positions.TOP_RIGHT;
			break;
		case 3:
			position = Positions.BOTTOM_LEFT;
			break;
		case 5:
			position = Positions.CENTER;
			break;
		default :
			position = Positions.BOTTOM_RIGHT;
			break;
		}
		try {
			Thumbnails.of(originFile).scale(1f).rotate(rotate)
			// 旋转
					.watermark(position, ImageIO.read(watermarkFile), HALF).outputQuality(HALF).toFile(outFile);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成缩略图
	 */
	public static void doThumb(final String originPath, final OutputStream os, final String format, final int height, final int width) {
		try {
			Thumbnails.of(originPath).size(height, width).outputFormat(format).toOutputStream(os);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成缩略图
	 */
	public static void doThumb(final File originFile, final int height, final int width) {
		try {
			BufferedImage originalImage = ImageIO.read(originFile);
			Thumbnails.of(originalImage).size(height, width).asBufferedImage();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成缩略图
	 */
	public static void doThumb(final File originFile) {
		try {
			BufferedImage originalImage = ImageIO.read(originFile);
			Thumbnails.of(originalImage).scale(QUARTER).asBufferedImage();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成缩略图
	 */
	public static void doThumb(final File originFile, final int rotate, final int height, final int width) {
		try {
			BufferedImage originalImage = ImageIO.read(originFile);
			@SuppressWarnings("unused")
			BufferedImage thumbnail = Thumbnails.of(originalImage).size(height, width).rotate(rotate).asBufferedImage();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成缩略图 加水印
	 */
	public static void doThumb(final File originFile, final int height, final int width, final File watermarkFile) {
		try {
			BufferedImage originalImage = ImageIO.read(originFile);
			BufferedImage watermarkImage = ImageIO.read(watermarkFile);
			Thumbnails.of(originalImage).size(height, width).watermark(Positions.BOTTOM_RIGHT, watermarkImage, HALF).asBufferedImage();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 是否是图片
	 * 
	 * @param ext
	 * @return "jpg", "jpeg", "gif", "png", "bmp" 为文件后缀名者为图片
	 */
	public static boolean isValidImageExt(final String ext) {
		String extStr = ext.toLowerCase(Locale.ENGLISH);
		for (String s : IMAGE_EXT) {
			if (s.equalsIgnoreCase(extStr)) {
				return true;
			}
		}
		return false;
	}

	// /**
	// * Checks if the underlying input stream contains an image.
	// *
	// * @param in
	// * input stream of an image
	// * @return <code>true</code> if the underlying input stream contains an image, else <code>false</code>
	// */
	// public static boolean isImage(final InputStream in) {
	// IoImageInfo ii = new IoImageInfo();
	// ii.setInput(in);
	// return ii.check();
	// }

	public static final int LT = 1; // 左上
	public static final int RT = 2; // 右上
	public static final int LB = 3; // 左下
	public static final int RB = 4; // 右下
	public static final int CENTER = 5; // 中央

	/**
	 * 获得水印位置
	 * 
	 * @param width
	 *            原图宽度
	 * @param height
	 *            原图高度
	 * @param p
	 *            水印位置 1-5，其他值为随机。1：左上；2：右上；3：左下；4：右下；5：中央。
	 * @param offsetx
	 *            水平偏移。
	 * @param offsety
	 *            垂直偏移。
	 * @return 水印位置
	 */
	public static Position markPosition(final int width, final int height, final int p, final int offsetx, final int offsety) {
		int position = 0;
		if (p < 1 || p > CENTER) {
			position = (int) (Math.random() * CENTER) + 1;
		}
		int x, y;
		switch (position) {
		case LT:
			x = offsetx;
			y = offsety;
			break;
		case RT:
			x = width + offsetx;
			y = offsety;
			break;
		// 左下
		case LB:
			x = offsetx;
			y = height + offsety;
			break;
		// 右下
		case RB:
			x = width + offsetx;
			y = height + offsety;
			break;
		// 中央
		case CENTER:
			x = (width / 2) + offsetx;
			y = (height / 2) + offsety;
			break;
		default:
			throw new RuntimeException("never reach ...");
		}
		return new Position(x, y);
	}

	/**
	 * 水印位置 包含左边偏移量，右边偏移量。
	 */
	@Data
	public static class Position {
		private int x;
		private int y;

		public Position(final int xx, final int yy) {
			this.x = xx;
			this.y = yy;
		}
	}
}
